﻿@using AliasVault.RazorComponents.Tables

<div class="mb-4">
    <Button Color="danger" OnClick="RevokeAllTokens">Revoke all sessions</Button>
</div>

<SortableTable Columns="@_refreshTokenTableColumns" SortColumn="@SortColumn" SortDirection="@SortDirection" OnSortChanged="HandleSortChanged">
    @foreach (var entry in SortedRefreshTokenList)
    {
        <SortableTableRow>
            <SortableTableColumn IsPrimary="true">@entry.Id</SortableTableColumn>
            <SortableTableColumn>@entry.DeviceIdentifier</SortableTableColumn>
            <SortableTableColumn>
                @if (!string.IsNullOrEmpty(entry.IpAddress))
                {
                    <a href="logging/auth?search=@Uri.EscapeDataString(entry.IpAddress)" class="cursor-pointer">@entry.IpAddress</a>
                }
                else
                {
                    <span>-</span>
                }
            </SortableTableColumn>
            <SortableTableColumn>@entry.CreatedAt.ToString("yyyy-MM-dd HH:mm")</SortableTableColumn>
            <SortableTableColumn>@entry.ExpireDate.ToString("yyyy-MM-dd HH:mm")</SortableTableColumn>
            <SortableTableColumn>
                <Button Color="danger" OnClick="() => RevokeRefreshToken(entry)">Revoke</Button>
            </SortableTableColumn>
        </SortableTableRow>
    }
</SortableTable>

@code {
    /// <summary>
    /// Gets or sets the list of refresh tokens to display.
    /// </summary>
    [Parameter]
    public List<AliasVaultUserRefreshToken> RefreshTokenList { get; set; } = [];

    /// <summary>
    /// Gets or sets the event callback to revoke a refresh token.
    /// </summary>
    [Parameter]
    public EventCallback<AliasVaultUserRefreshToken> OnRevokeToken { get; set; }

    /// <summary>
    /// Gets or sets the event callback to revoke all refresh tokens.
    /// </summary>
    [Parameter]
    public EventCallback OnRevokeAllTokens { get; set; }

    private string SortColumn { get; set; } = "CreatedAt";
    private SortDirection SortDirection { get; set; } = SortDirection.Descending;

    private readonly List<TableColumn> _refreshTokenTableColumns = [
        new TableColumn { Title = "ID", PropertyName = "Id" },
        new TableColumn { Title = "Device", PropertyName = "DeviceIdentifier" },
        new TableColumn { Title = "Ip", PropertyName = "IpAddress" },
        new TableColumn { Title = "Created", PropertyName = "CreatedAt" },
        new TableColumn { Title = "Expires", PropertyName = "ExpireDate" },
        new TableColumn { Title = "Actions", Sortable = false },
    ];

    private IEnumerable<AliasVaultUserRefreshToken> SortedRefreshTokenList => SortList(RefreshTokenList, SortColumn, SortDirection);

    private void HandleSortChanged((string column, SortDirection direction) sort)
    {
        SortColumn = sort.column;
        SortDirection = sort.direction;
        StateHasChanged();
    }

    private static IEnumerable<AliasVaultUserRefreshToken> SortList(List<AliasVaultUserRefreshToken> refreshTokens, string sortColumn, SortDirection sortDirection)
    {
        return sortColumn switch
        {
            "Id" => SortableTable.SortListByProperty(refreshTokens, r => r.Id, sortDirection),
            "DeviceIdentifier" => SortableTable.SortListByProperty(refreshTokens, r => r.DeviceIdentifier, sortDirection),
            "IpAddress" => SortableTable.SortListByProperty(refreshTokens, r => r.IpAddress, sortDirection),
            "CreatedAt" => SortableTable.SortListByProperty(refreshTokens, r => r.CreatedAt, sortDirection),
            "ExpireDate" => SortableTable.SortListByProperty(refreshTokens, r => r.ExpireDate, sortDirection),
            _ => refreshTokens
        };
    }

    private async Task RevokeRefreshToken(AliasVaultUserRefreshToken entry)
    {
        await OnRevokeToken.InvokeAsync(entry);
    }

    private async Task RevokeAllTokens()
    {
        if (await ConfirmModalService.ShowConfirmation(
            title: "Confirm Revoke All Tokens",
            message: @"Are you sure you want to revoke all refresh tokens?

Important notes:
• This will log out the user from all their devices.
• They will need to log in again on each device.
• This action cannot be undone.

Do you want to proceed with revoking all tokens?"))
        {
            await OnRevokeAllTokens.InvokeAsync();
        }
    }
}
